package com.swdegao.iot.netty.utils;

import io.netty.channel.Channel;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author:AwakeningCode
 * @Date: Created in 11:29 2018\2\5 0005
 */
public class Const {
    //定义一个全局的记录器，通过LoggerFactory获取
    private final static Logger logger = LoggerFactory.getLogger(Const.class);
    //帧头
    public static final Byte HEAD = (byte) 0x80;
    //帧尾
    public static final Byte[] TAIL = {(byte) 0x0d,(byte) 0x0a};
    //控制锁状态
    public static final String CONTROL_TYPE = "s";
    //24锁 全部关闭状态
    public static final String LOCKS = "nnnnnnnnnnnnnnnnnnnnnnnn";
    //开锁标识
    public static final char OPEN = 'y';
    //客户端执行结果
    public static final String RESULT_TYPE = "j";
    //客户端执行测试结果
    public static final String RESULT_TEXT = "t";
    //服务器执行结果
    public static final String SUCCESS = "yyyyyyyyyyyyyyyyyyyyyyyy";
    public static final String ERROR = "nnnnnnnnnnnnnnnnnnnnnnnn";

    private static Map<String,Channel> map = new ConcurrentHashMap<String, Channel>();

    /**
     * Netty连接池添加连接
     * @param clientId 连接ID
     * @param channel 连接实例
     */
    public static void add(String clientId,Channel channel){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //logger.info("add ChannelId: " + clientId + " " + formatter.format(new Date()));
        map.put(clientId,channel);
    }

    /**
     * 判断是否存在该连接ID实例
     * @param channelID 连接Id
     * @return
     */
    public static boolean hasChannelID(String channelID){
        boolean state = map.containsKey(channelID);
        return state;
    }
    /**
     * 判断是否存在该连接ID实例
     * @param channelID 连接Id
     * @return
     */
    public static boolean ischangeChannelID(String channelID,Channel channel){
        boolean flag = false;
        if(map.containsKey(channelID)){
            if(channel!=map.get(channelID)){
                flag = true;
            }
        }
        return flag;
    }
    /**
     * 根据连接ID 获取连接实例
     * @param clientId 链接Id
     * @return
     */
    public static Channel get(String clientId){
        return map.get(clientId);
    }
    /**
     * 根据连接ID 获取连接实例状态
     * @param clientId 链接Id
     * @return
     */
    public static String getChannelStatus(String clientId){
        String flag = "0";
        Channel channel = map.get(clientId);
        if(channel!=null && channel.isActive()) flag = "1";
        return flag;
    }

    /**
     * 根据channel 获取channnelId
     * @param clientId 链接Id
     * @return
     */
    public static String getChannelIds(Channel channel){
        String channelIds = "";
        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
            if (entry.getValue()==channel){
                channelIds = "".equals(channelIds)? entry.getKey().toString() : channelIds+entry.getKey().toString();
            }
        }
        return channelIds;
    }

    /**
     * 根据链接实例移除链接实例
     * @param channel 链接实例
     */
    public static void remove(Channel channel){
        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
            if (entry.getValue()==channel){
                map.remove(entry.getKey());
            }
        }
    }

    /**
     * 获取链接数组个数
     * @return
     */
    public static int getSzie(){
        return map.size();
    }

    /**
     * 获取链接数组Id
     * @return
     */
    public static Set<String> getIdList(){
        return map.keySet();
    }

    /**
     * 获取连接池数据信息
     */
    public static void mapInfo(){
        System.out.println("channel size : " + map.size());
        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
            // System.out.println("clientId: " + entry.getKey());
        }
    }

    /**
     * 链接实例是否存在链接池中
     * @param channel 链接实例
     * @return 链接Id
     */
    public static String isChannel(Channel channel){
//        logger.info("连接数：" + map.entrySet().size());
        String clientId = null;
        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
            if (entry.getValue() == channel){
                clientId = (String) entry.getKey();
            }
        }
        return clientId;

    }


    public static String isChannelAndChangeClientId(Channel channel,String imei){
//        logger.info("连接数：" + map.entrySet().size());
        String clientId = null;
        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
            if (entry.getValue() == channel){
                clientId = (String) entry.getKey();
                break;
            }
        }
        map.remove(clientId);
        map.put(imei,channel);
        return clientId;//UUID

    }

    public static String isChannelAndChangeClientIdByUUID(String channelUUID,String imei){
//        logger.info("连接数：" + map.entrySet().size());
        Channel channel = map.get(channelUUID);
        map.remove(channelUUID);
        map.put(imei,channel);
        return channelUUID;//UUID




//        String clientId = null;
//        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
//            if (entry.getValue() == channel){
//                clientId = (String) entry.getKey();
//                break;
//            }
//        }
//        map.remove(clientId);
//        map.put(imei,channel);
//        return clientId;//UUID

    }



    /**
     * 更新链接实例Id
     * @param clientId 原始ID
     * @param newID 新的连接ID
     */
    public static void ChangeClientId(String clientId,String newID){
        for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
            if (entry.getKey()==clientId){
                //logger.info("ChangeClientId,clientId " +clientId+",newID"+newID);
                Channel channel = (Channel) entry.getValue();
                map.remove(entry.getKey());
                map.put(newID,channel);
            }
        }
    }

    public static void removeRealChannel(String channelID) {
        Channel channel1 = get(channelID);
        if(channel1.isActive()){
            channel1.close();
        }

    }

    //原版
//    public static void changeChannel(String channelID, Channel channel) {
//
//    	try {
//    		Channel channel1 = get(channelID);
//        	if(channel != channel1 && channel1.isActive()){
//        		channel1.close();
//        		//logger.info(channelID+"channel删除！");
//        	}
//    		for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
//                if (entry.getKey().equals(channelID)){
//                    map.remove(entry.getKey());
//                }
//                if (entry.getValue() == channel){
//                    map.remove(entry.getKey());
//                }
//            }
//        	if(!map.containsKey(channelID))map.put(channelID,channel);
//		} catch (Exception e) {
//			// TODO: handle exception
//			logger.info(channelID+e.getMessage());
//		}
//    }

    //改动测试-LX 2023-12-14  for循环优化掉
    public static void changeChannel(String channelID, Channel channel) {

        try {
            Channel channel1 = get(channelID);
            if(channel != channel1 && channel1.isActive()){
                channel1.close();
                //logger.info(channelID+"channel删除！");
            }
//            for (@SuppressWarnings("rawtypes") Map.Entry entry:map.entrySet()){
//                if (entry.getKey().equals(channelID)){
//                    map.remove(entry.getKey());
//                }
//                if (entry.getValue() == channel){
//                    map.remove(entry.getKey());
//                }
//            }
            map.remove(channelID);
            if(!map.containsKey(channelID))map.put(channelID,channel);
        } catch (Exception e) {
            // TODO: handle exception
            logger.info(channelID+e.getMessage());
        }
    }



    public enum StateEnum{
        SUCCESS(1,"ok"),
        FALID(2,"no");
        private int state;

        private String stateInfo;

        StateEnum(int state, String stateInfo) {
            this.state = state;
            this.stateInfo = stateInfo;
        }

        public int getState() {
            return state;
        }

        public void setState(int state) {
            this.state = state;
        }

        public String getStateInfo() {
            return stateInfo;
        }

        public void setStateInfo(String stateInfo) {
            this.stateInfo = stateInfo;
        }

        public static StateEnum stateOf(int index){
            for (StateEnum item:values()){
                if (item.getState() == index){
                    return item;
                }
            }
            return null;
        }
    }

}
